package com.hunter.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.JWindow;
import javax.swing.SwingWorker;
import javax.swing.border.BevelBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import org.apache.log4j.Logger;
import org.apache.lucene.search.Query;

import com.hunter.desktop.file.FileData;
import com.hunter.lucene.util.search.QuerySession;
import com.hunter.lucene.util.search.Searchable;
import com.hunter.util.ConfigManager;
import com.hunter.util.HistoryUtil;
import com.hunter.util.LogUtil;
import com.hunter.util.PropertiesUtil;
import com.hunter.util.QueryManager;
import com.hunter.util.SystemUtil;
import com.mkk.swing.SwingUtil;

/**
 * 2010-9-1 下午10:34:46<br>
 * 主界面中间面板
 * 
 * @author mkk
 */
public class MainPanel extends JPanel {

	private static Logger log = Logger.getLogger(MainPanel.class);
	private static final long serialVersionUID = 1L;

	// 搜索框
	private JTextField textfield1;
	// 搜索按钮
	private JButton button1;
	// main
	private MainFrame main;
	// autocomplete window
	private JWindow window;
	// autocomplete result list
	private JList list;
	// SearchPanel,maybe is null
	private SearchPanel searchPanel;
	// 高级搜索标签
	private JLabel label1;
	// 高级搜索面板,默认是隐藏的
	private JPanel panel1;
	// 高级搜索界面组件
	private String[] labStrs = { "搜索隐藏文件", "搜索文件内容", "指定时间段搜索", "指定后缀名搜索" };
	private JLabel labs[] = new JLabel[labStrs.length];
	private JCheckBox boxs[] = new JCheckBox[labStrs.length];

	private HistoryUtil historyUtil = HistoryUtil.getHistoryUtil();

	public MainPanel(MainFrame main) {
		this.main = main;
		this.initComponents();
		this.processEvents();
	}

	/**
	 * 初始化组件
	 */
	private void initComponents() {
		Box box = Box.createVerticalBox();
		// 显示搜索框的面板
		JPanel panel2 = new JPanel();
		this.setLayout(new FlowLayout(FlowLayout.CENTER));
		this.textfield1 = new JTextField(50);
		this.textfield1.setToolTipText("输入搜索内容");
		this.textfield1.setBackground(Color.WHITE);
		this.textfield1.setFont(new Font("新宋体", Font.BOLD, 13));
		this.textfield1.setBorder(BorderFactory
				.createBevelBorder(BevelBorder.LOWERED));
		panel2.add(this.textfield1);
		this.button1 = new JButton();
		button1.setIcon(SystemUtil.getSearchIcon());
		button1.setBorder(BorderFactory.createEmptyBorder());
		this.button1.setToolTipText("搜索");
		panel2.add(this.button1);
		this.label1 = new JLabel("<html><a href='#'>高级</a></html>");
		this.label1.setToolTipText("高级搜索");
		this.label1.setCursor(new Cursor(Cursor.HAND_CURSOR));
		panel2.add(this.label1);
		// 上边空格
		box.add(Box.createVerticalStrut(180));
		JPanel panel3 = new JPanel();
		panel3.setLayout(new BorderLayout());
		// 高级搜索面板
		this.panel1 = new JPanel();
		this.panel1.setVisible(false);
		panel3.add(panel2, BorderLayout.NORTH);
		panel3.add(this.panel1, BorderLayout.CENTER);
		box.add(panel3);
		// 下面空格
		box.add(Box.createVerticalStrut(250));
		this.add(box);
		// 高级搜索面板
		initTopSearchPanel();
	}

	/**
	 * 高级面板初始化
	 */
	private void initTopSearchPanel() {
		this.panel1.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
		this.panel1.setLayout(new BorderLayout(1, 1));
		// north
		JPanel p = null;
		// center
		p = new JPanel(new GridLayout(labStrs.length, 2));
		for (int i = 0; i < labStrs.length; i++) {
			boxs[i] = new JCheckBox(labStrs[i]);
			labs[i] = new JLabel();
			p.add(boxs[i]);
			p.add(labs[i]);
		}
		panel1.add(p, BorderLayout.CENTER);
	}

	/**
	 * @return the textfield1
	 */
	public JTextField getTextfield1() {
		return textfield1;
	}

	/**
	 * 事件处理
	 */
	private void processEvents() {
		this.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				disposeWindow();
			}
		});
		// 高级搜索事件
		this.label1.addMouseListener(new MouseAdapter() {

			public void mouseClicked(MouseEvent e) {
				disposeWindow();
				boolean visiable = panel1.isVisible();
				if (visiable) {
					label1.setText("<html><a href='#'>高级</a></html>");
					label1.setToolTipText("高级搜索");
				} else {
					label1.setText("<html><a href='#'>关闭</a></html>");
					label1.setToolTipText("关闭高级搜索");
				}
				panel1.setVisible(!visiable);
			}

			public void mouseEntered(MouseEvent e) {
				main.setInfo(label1.getToolTipText(), Color.BLACK);
			}

			public void mouseExited(MouseEvent e) {
				main.setInfo("欢迎使用 Hunter 1.0", Color.BLACK);
			}
		});
		/*
		 * 搜索事件
		 */
		final ActionListener listener1 = new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				searchAction();
			}
		};
		this.textfield1.addActionListener(listener1);
		this.button1.addActionListener(listener1);
		/**
		 * 搜索框查看历史搜索词事件(点击键盘PageUP,PageDown键触发)
		 */
		this.textfield1.addKeyListener(new KeyListener() {

			@Override
			public void keyTyped(KeyEvent e) {
				// Do nothing in here
			}

			@Override
			public void keyReleased(KeyEvent e) {
				if (KeyEvent.VK_PAGE_DOWN == e.getKeyCode()) {
					String nkey = historyUtil.getNextKeyword();
					if (SystemUtil.hasText(nkey)) {
						textfield1.setText(nkey);
					}
				}
				if (KeyEvent.VK_PAGE_UP == e.getKeyCode()) {
					String nkey = historyUtil.getPreviousKeyword();
					if (SystemUtil.hasText(nkey)) {
						textfield1.setText(nkey);
					}
				}
			}

			@Override
			public void keyPressed(KeyEvent e) {
				// Do nothing in here
			}
		});
		/*
		 * 自动补全事件
		 */
		this.textfield1.getDocument().addDocumentListener(
				new DocumentListener() {

					@Override
					public void removeUpdate(DocumentEvent e) {
						autoComplate();
					}

					@Override
					public void insertUpdate(DocumentEvent e) {
						autoComplate();
					}

					@Override
					public void changedUpdate(DocumentEvent e) {
						// Do nothing in here
					}
				});
	}

	/**
	 * Search event
	 */
	private void searchAction() {
		// 检查是否有索引文件
		if (!SystemUtil.isIndexFileExist()) {
			// 没有则弹出提示框
			int i = SwingUtil.showConfirmInfo(main, "提示",
					"尚未创建索引文件,不能搜索!\n点击 \"确定\" 创建索引文件");
			if (i == JOptionPane.YES_OPTION) {
				SettingDialog sd = main.getSetDialog();
				if (sd == null) {
					sd = new SettingDialog(main, true);
					Point p = SwingUtil.getStartPoint(sd.getWidth(), sd
							.getHeight());
					sd.setLocation(p);
				}
				sd.setVisible(true);
			}
			return;
		}
		// 1.获取搜索关键字
		String s = textfield1.getText().trim();
		if (s.length() == 0) {
			main.setInfo("没有输入关键字,不能搜索", Color.RED);
			return;
		}
		/*
		 * If complete window is show and have select value ,get the value to
		 * keyword
		 */
		if (window != null && window.isVisible()) {
			if (list.getSelectedIndex() != -1) {
				s = list.getSelectedValue().toString();
				textfield1.setText(s);
			}
		}
		disposeWindow();
		final String keyword = s;
		main.setInfo("搜索中,请稍候...", Color.BLUE);
		button1.setEnabled(false);
		textfield1.setEnabled(false);
		final JProgressBar bar = main.getjProgressBar1();
		// 启动搜索
		SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {

			protected Void doInBackground() throws Exception {
				bar.setVisible(true);
				long start = System.currentTimeMillis();
				QuerySession querySession = null;
				try {
					publish(5);
					Searchable searcher = ConfigManager.getManager()
							.getSearcher();
					publish(10);
					// 根据用户的设置创建查询对象Query, 默认使用IK查询
					Query query = QueryManager.getQueryManager().getQuery(
							keyword);
					publish(20);
					querySession = searcher.createQuerySession(query);
					publish(40);
					querySession.execute();
					publish(60);
					List<FileData> resList = new ArrayList<FileData>();
					while (querySession.hasMore()) {
						resList.add((FileData) querySession.next());
					}
					publish(80);
					// 搜索时间
					long times = (System.currentTimeMillis() - start);
					// 创建搜索结果面板并显示
					searchPanel = new SearchPanel(main, keyword, times, resList);
					searchPanel.setFirstShow(false);
					JPanel panel = main.getPanel1();
					panel.add(searchPanel, MainFrame.SEARCH_PANEL_NAME);
					main.getCardLayout().show(panel,
							MainFrame.SEARCH_PANEL_NAME);
					searchPanel.getTextField1().requestFocus();
					// 设置回首页可用
					main.getLabel3().setVisible(true);
					publish(100);
					// Save keyword
					historyUtil.saveKeyword(keyword);
				} catch (Exception e) {
					if (log.isDebugEnabled()) {
						log.debug("搜索异常", e);
					}
					// 保存异常日志
					LogUtil.saveExceptionLog(e);
					// 弹出错误信息显示界面
					main.setInfo("搜索异常", Color.RED);
					SwingUtil.showErrorInfo(main, "异常", "搜索异常,信息:\n"
							+ e.getMessage());

				} finally {
					if (querySession != null) {
						querySession.close();
					}
				}

				return null;
			}

			protected void process(List<Integer> chunks) {
				for (int i : chunks) {
					bar.setValue(i);
				}
			}

			protected void done() {
				main.setInfo("搜索完成", Color.BLUE);
				button1.setEnabled(true);
				textfield1.setEnabled(true);
				bar.setVisible(false);
			}

		};
		worker.execute();
	}

	/**
	 * 自动补全的实现方法
	 */
	private void autoComplate() {
		// Check switch
		if (!PropertiesUtil.AUTO_COMPLATE_OPEN) {
			return;
		}
		// Check input text
		String key = textfield1.getText().trim();
		if (!SystemUtil.hasText(key)) {
			disposeWindow();
			return;
		}
		String results[] = ConfigManager.getManager().suggestion(key);
		if (results == null || results.length == 0) {
			disposeWindow();
			return;
		}
		// Open window
		showAutocompleteWindow(results);
	}

	/**
	 * Show autocomplete window
	 * 
	 * @param results
	 *            Search results
	 */
	private void showAutocompleteWindow(String[] results) {
		// Create window
		createWindow(results.length);
		list = new JList(results);
		list.setBorder(BorderFactory.createLineBorder(Color.black));
		window.add(list, BorderLayout.CENTER);
		window.setVisible(true);
		textfield1.requestFocus();
		// add event
		list.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (list.getSelectedIndex() != -1) {
					textfield1.setText(list.getSelectedValue().toString());
					searchAction();
				}
			}
		});
		// Mouse move event
		list.addMouseMotionListener(new MouseMotionAdapter() {
			@Override
			public void mouseMoved(MouseEvent e) {
				int index = list.locationToIndex(e.getPoint());
				if (list.getSelectedIndex() != index) {
					list.setSelectedIndex(index);
				}
			}
		});
		// Mouse exist event
		list.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseExited(MouseEvent e) {
				list.clearSelection();
			}
		});
	}

	/**
	 * Create autocomplete window,if have old window,then dispose old, after
	 * create new window
	 * 
	 * @param length
	 *            Search results size
	 */
	private void createWindow(int length) {
		disposeWindow();
		window = new JWindow(main);
		window.setLayout(new BorderLayout());
		Point point = this.textfield1.getLocationOnScreen();
		window.setLocation(point.x, point.y + 21);
		window.setSize(textfield1.getSize().width, 18 * length);
	}

	/**
	 * Dispose auto complete window,if it is visible true
	 * <p>
	 * Current package can visit
	 */
	void disposeWindow() {
		if (window != null) {
			if (window.isVisible()) {
				window.dispose();
			}
		}
		// Dispose searchPanel window,if is show
		if (searchPanel != null) {
			searchPanel.disposeWindow();
		}
	}

}
